package com.swak.netty.exception;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

import com.swak.Constants;
import com.swak.OS;
import com.swak.exception.RemotingException;
import com.swak.reactivex.threads.Contexts;
import com.swak.reactivex.transport.Channel;
import com.swak.reactivex.transport.ExchangeChannel;
import com.swak.reactivex.transport.ExchangeClient;
import com.swak.reactivex.transport.ExchangeHandlerAdapter;
import com.swak.reactivex.transport.Exchangers;
import com.swak.reactivex.transport.TransportMode;
import com.swak.reactivex.transport.resources.LoopResources;
import com.swak.registry.URL;
import com.swak.utils.Fmt;
import com.swak.utils.Maps;

/**
 * 这是一款比较通用的基于  TCP 的通信服务
 * 
 * @author 618lf
 */
public class Client extends ExchangeHandlerAdapter {

	private LoopResources resources = Contexts.createEventLoopResources(TransportMode.OS, 1, 2, "Test.EventLoop-",
			false, 2, TimeUnit.SECONDS);

	ExchangeClient channel;
	URL url;

	public Client() throws RemotingException {
		Map<String, String> parameters = Maps.newHashMap();
		parameters.put(Constants.Bind_Host, Constants.ANYHOST);
		parameters.put(Constants.Heartbeat, String.valueOf(Constants.Default_Heartbeat));
		//parameters.put(Constants.PAYLOAD_KEY, "20480"); // 最大 1024 byte
		parameters.put(Constants.Timeout, "30000"); // 设置一个大一点的超时时间
		this.url = new URL("Test", OS.ip(), 10889, parameters);
		this.channel = Exchangers.connect(url, resources, this);
	}

	@Override
	public void sent(Channel channel, Object message) throws RemotingException {
		Fmt.out.println("数据发送成功！：" + message);
	}

	// ######## 偏请求的数据，不会回调响应 ###############
	@Override
	public void received(Channel channel, Object message) throws RemotingException {
		Fmt.out.println("收到数据：" + message);
	}

	@Override
	public CompletionStage<Object> reply(ExchangeChannel channel, Object message) throws RemotingException {
		Fmt.out.println("客户端收到请求：" + message);
		return CompletableFuture.completedFuture(message);
	}

	@Override
	public void caught(Channel channel, Throwable exception) throws RemotingException {
		Fmt.err.println(exception);
	}

	public static void main(String[] args)
			throws RemotingException, InterruptedException, ExecutionException, FileNotFoundException {
		Client client = new Client();
		ExchangeClient channel = client.channel;

		// 测试异常的情况

		// 1. 不支持的编码类型 -- 会显示异常
		// channel.send("String 数据");

		// 2. 模拟一个编码过程中内部异常：非请求和响应
		// channel.send(Message.forMessage().setData("数据"));

		// 3. 模拟一个编码过程中内部异常：非强制请求
		// byte[] data = new byte[512];
		// channel.send(Message.forRequest().setData(data));

		// 4. 模拟一个编码过程中内部异常：强制请求(这是真正的请求)
//		CompletableFuture<Object> future = channel.request(Message.forRequest().setData(data));
//		future.whenComplete((r, t) -> {
//			Fmt.out.println("请求结果：" + r);
//			if (t != null) {
//				t.printStackTrace();
//			}
//		});

		// 5.推送数据
		// channel.send(Message.forResponse(Message.forRequest()).setData("数据"));

		// 6.推送数据
		// channel.send(Message.forMessage().setData("数据"));

		// 7.发送文件
		File file = new File("D:\\bigtext.txt");
		channel.sendFile(file, false);
	}
}
